﻿<%@ WebHandler Language="C#" Class="Apollo.Website.TypeDefinitionHandler" %>

using System;
using System.Web;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using Apollo;
using NHibernate;
using NHibernate.Criterion;

namespace Apollo.Website
{
    public class TypeDefinitionHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/javascript";
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

            try
            {
                int entityID = 0;
                string path = context.Request["path"];

                int.TryParse(context.Request["entityID"], out entityID);

                // find base entity
                Entity entity = Application.Meta<Entity>().SingleOrDefault<Entity>(e => e.Id == entityID);

                Apollo.Core.Projection projection = null;

                if (!string.IsNullOrEmpty(path))
                {
                    // follow the path
                    projection = new Apollo.Core.Projection(path, entity.MappedClass);

                    // find actual entity
                    entity = Application.Meta<Entity>().SingleOrDefault<Entity>(e => e.Name == projection.ClassType.Name);
                }

                if (entity == null)
                {
                    context.Response.Write("{\"type\": \"Not found\"}");
                }
                else
                {
                    // respose with type
                    string contextJSON = "{\"type\": \"" + entity.MappedClass.FullName + "\", \"entityID\": \"" + entityID.ToString() + "\"";
                    string columnsDefinition = "";

                    foreach (EntityProperty p in Application.Meta<EntityProperty>().Where<EntityProperty>(ep => ep.Entity.Id == entity.Id).OrderBy<EntityProperty, string>(ep => ep.PropertyName))
                    {
                        try
                        {
                            Apollo.Core.Projection propProj = new Apollo.Core.Projection(p.PropertyName, entity.MappedClass);

                            if (!propProj.IsValid)
                                continue;

                            if (columnsDefinition != "")
                                columnsDefinition += ",";

                            string name = p.PropertyName;
                            string displayName = propProj.DisplayName;

                            if (projection != null)
                            {
                                name = path + "." + name;
                                displayName = projection.DisplayName + " > " + displayName;
                            }

                            columnsDefinition += "{\"name\": \"" + name + "\", \"fieldType\": \"" + propProj.PropertyTypeForJSON + "\", \"displayName\":\"" + displayName + "\"}";
                        }
                        catch
                        {

                        }
                    }


                    contextJSON += ", \"columns\": [" + columnsDefinition + "]}";
                    context.Response.Write(contextJSON);
                }
            }
            catch (Exception ex)
            {
                Apollo.Application.LogError(ex);
                
                context.Response.Write("{\"type\": \"Not found\"}");
            }
        }


        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

    }
}